//
//  MANetworkTool.m
//  MateAdv
//
//  Created by 茶 on 2023/9/8.
//

#import "MANetworkTool.h"

#import <AFNetworking/AFNetworking.h>

static MANetworkTool *netTool;

#if DEBUG
NSString *const  KBaseUrl = @"http://zxh.xtboo.com";
#else
NSString *const  KBaseUrl = @"http://zxh.xtboo.com";
#endif

@interface MANetworkTool ()

@property (nonatomic, copy) NSDictionary *defaultParam;

@end

@implementation MANetworkTool {
    AFHTTPSessionManager *_manager;
    AFURLSessionManager *_downLoadManager;
    AFHTTPResponseSerializer<AFURLResponseSerialization> *_defalutResponseSerializer;
    AFHTTPRequestSerializer<AFURLRequestSerialization> *_defalutRequestSerializer;
    
    dispatch_semaphore_t _semaphore;
}

#pragma mark -- public
- (void)ma_post:(NSString *)urlString params:(NSDictionary *)params successed:(void(^)(id object, BOOL isCache))successed failed:(nullable void(^)(NSError * ))failed {
    NSString *url = [KBaseUrl stringByAppendingString:urlString];
    NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithDictionary:self.defaultParam];
    if (params) [dic addEntriesFromDictionary:params];
    if (![self _ma_preparRequesetWithURL:url faileConfig:failed]) return;
    
    NSString *code = [dic encodedJsonString];
    code = [code AES128EncryptWithKey:@"bbd3klk1c6039f99" iv:@"abd1rb23c663dfcc"];
    NSDictionary *parameters = @{};
    if (code) {
        parameters = @{@"code" : code};
    }
    MAWeakify(self);
    [_manager POST:url parameters:parameters headers:_requestHeader progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        MAStrongify(self);
        [self _ma_getDataSuccessedWithResponseObject:responseObject url:url params:params successed:successed failed:failed];
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        if (error.code != -999) {
            MABlock(failed, error);
        }
    }];
}

+ (MANetStatusType)ma_getNetStatus {
    return (MANetStatusType)[AFNetworkReachabilityManager sharedManager].networkReachabilityStatus;;
}

#pragma mark -- pravicy
- (instancetype)init
{
    self = [super init];
    if (self) {
        _manager = [AFHTTPSessionManager manager];
        _defalutRequestSerializer = _manager.requestSerializer;
        _defalutResponseSerializer = _manager.responseSerializer;
        [_manager setSessionDidBecomeInvalidBlock:^(NSURLSession * _Nonnull session, NSError * _Nonnull error) {
            [session invalidateAndCancel];
        }];
        _downLoadManager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
        [_downLoadManager setSessionDidBecomeInvalidBlock:^(NSURLSession * _Nonnull session, NSError * _Nonnull error) {
            [session invalidateAndCancel];
        }];
        _semaphore = dispatch_semaphore_create(1);
        _timeoutInterval = 30;
        
        _manager.securityPolicy = [self _ma_customSecurityPolicy];
        _downLoadManager.securityPolicy = [self _ma_customSecurityPolicy];
    }
    return self;
}

- (BOOL)_ma_preparRequesetWithURL:(NSString *)urlString faileConfig:(void(^)(NSError * error))faileConfig{
    NSAssert(urlString.length, @"url不能为空");
    if ([MANetworkTool ma_getNetStatus] == MANetStatusTypeNotReachable) {
        NSError *error = [NSError errorWithDomain:NSURLErrorDomain code:-1009 userInfo:@{@"CodeDes" : @"网络似乎已经断开链接"}];
        MABlock(faileConfig, error);
        return NO;
    }
    [self _ma_mangerConfig];
    return YES;
}

- (void)_ma_getDataSuccessedWithResponseObject:(id)responseObject url:(NSString *)url params:(NSDictionary *)params successed:(void(^)(id object, BOOL isCache))successed failed:(nullable void(^)(NSError * ))failed {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        id checkResponseObject = responseObject;
        if ([checkResponseObject containKey:@"code"]) {
            NSString *str = responseObject[@"code"];
            NSDictionary *dic = [[str AES128DecryptWithkey:@"bbd3klk1c6039f99" iv:@"abd1rb23c663dfcc"] jsonValue];
            NSDictionary *data = nil;
            if ([dic containKey:@"data"]) {
                data = dic[@"data"];
            }
            if (![data isKindOfClass:NSNull.class] && [data containKey:@"status"] && [data[@"status"] intValue] == -1) {
                NSString *msg = data[@"msg"];
                NSError *error = nil;
                if (msg) {
                    error = [NSError errorWithDomain:NSUnderlyingErrorKey code:-1 userInfo:@{NSLocalizedDescriptionKey : msg}];
                } else {
                    error = [NSError errorWithDomain:NSUnderlyingErrorKey code:-1 userInfo:nil];
                }
                dispatch_async(dispatch_get_main_queue(), ^{
                    MABlock(failed, error);
                });
                return;
            } else if ([data isKindOfClass:NSNull.class]) {
                data = @{};
            }
            checkResponseObject = data;
        }
        dispatch_async(dispatch_get_main_queue(), ^{
            MABlock(successed, checkResponseObject, NO);
        });
    });
}

- (void)_ma_mangerConfig{
    dispatch_semaphore_wait(_semaphore, DISPATCH_TIME_FOREVER);
    if (_jsonRequest) {
        _manager.requestSerializer = [AFJSONRequestSerializer serializer];
    }
    if (_supportcontentType) {
        _manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", @"text/palin",nil];
    }
    _manager.requestSerializer.timeoutInterval = _timeoutInterval;
    dispatch_semaphore_signal(_semaphore);
}

- (AFSecurityPolicy *)_ma_customSecurityPolicy {
    AFSecurityPolicy *securitypolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone];
    [securitypolicy setAllowInvalidCertificates:YES];
    [securitypolicy setValidatesDomainName:NO];
    return securitypolicy;
}

- (NSDictionary *)defaultParam {
    NSString *oaid = @"";
    if (_userUUID) {
        oaid = _userUUID;
    } else if (MAUserObj(kUserUUidKey)) {
        oaid = MAUserObj(kUserUUidKey);
    }
    NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithDictionary:@{@"oaid" : oaid, @"platform" : @"ios", @"version" : kApplication.appVersion, @"channel" : @"Apple"}];
    if (MAUserObj(kUserToken)) {
        [dic setObject:MAUserObj(kUserToken) forKey:@"token"];
    }
    _defaultParam = dic.copy;
    return _defaultParam;
}

@end
